package com.seqb.system.filter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.seqb.common.ResultVo;
import com.seqb.common.utils.JwtUtils;
import com.seqb.manage.user.dao.UserDao;
import com.seqb.manage.user.domain.UserDO;
import com.seqb.system.domain.JwtToken;
import com.seqb.utils.HttpServletUtils;
import com.seqb.utils.JsonUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @author lilinshen
 * @title 请填写标题
 * @description 请填写相关描述
 * @date 2019/12/24
 */
public class JwtFilter implements Filter {

    private UserDao userDao;

    public JwtFilter(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        try {
            String token = request.getHeader("token");
            JwtToken jwtToken = new JwtToken(token);
            ResultVo resultVo = ResultVo.error();
            try {
                //提交给realm进行登入
                SecurityUtils.getSubject().login(jwtToken);
                chain.doFilter(servletRequest, servletResponse);
                return;
            } catch (AuthenticationException e) {
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json;charset=utf-8");
                PrintWriter printWriter = response.getWriter();
                if (e.getMessage().indexOf("expired") > 0) {
                    //token超时失效，重新登录（超过2倍时间）
                    Long expired = JwtUtils.getExpired(token);
                    if (expired < System.currentTimeMillis()) {
                        resultVo.put("msg", "token失效，重新登录！");
                        resultVo.put("code", "2");
                        printWriter.print(JsonUtils.beanToJson(resultVo));
                        printWriter.close();
                        return;
                    }
                    //token超时失效，可以刷新（没超2倍时间）
                    String account = JwtUtils.getAccount(token);
                    QueryWrapper queryWrapper = new QueryWrapper();
                    queryWrapper.eq("account", account);
                    UserDO user = userDao.selectOne(queryWrapper);
                    if (null == user) {
                        resultVo.put("msg", "账号不存在，重新登录！");
                        resultVo.put("code", "2");
                        printWriter.print(JsonUtils.beanToJson(resultVo));
                        printWriter.close();
                        return;
                    }
                    String newToken = JwtUtils.sign(user.getAccount(), user.getPassword());
                    resultVo.put("msg", "token失效，重新刷新！");
                    resultVo.put("token", newToken);
                    resultVo.put("code", "3");
                    printWriter.print(JsonUtils.beanToJson(resultVo));
                    printWriter.close();
                    return;
                } else if (e.getMessage().indexOf("empty") > 0) {
                    resultVo.put("msg", "token不能为空，重新登录！");
                    resultVo.put("code", "2");
                    printWriter.print(JsonUtils.beanToJson(resultVo));
                    printWriter.close();
                    return;
                }
                resultVo.put("msg", "token失效，重新登录！");
                resultVo.put("code", "2");
                printWriter.print(JsonUtils.beanToJson(resultVo));
                printWriter.close();
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void destroy() {

    }

    @Override
    public void init(FilterConfig filterConfig) {

    }

}